using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using DocumentCreationSystem.Models;
using DocumentCreationSystem.Services;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using System.Text.Json;
using System.Text.Json.Serialization;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Threading;
using System;
using System.Linq;
using System.IO;
using System.Diagnostics;

namespace DocumentCreationSystem.Views;

/// <summary>
/// AI模型配置窗口
/// </summary>
public partial class AIModelConfigWindow : Window
{
    private readonly IServiceProvider _serviceProvider;
    private readonly ILogger<AIModelConfigWindow> _logger;
    private readonly IConfiguration _configuration;
    private readonly HttpClient _httpClient;
    private readonly IToolApiConfigService _toolApiConfigService;
    private readonly CustomModelService _customModelService;
    private AIModelConfig _currentConfig = null!;
    private ToolApiConfig _currentToolApiConfig = null!;

    public AIModelConfig? Result { get; private set; }

    public AIModelConfigWindow(IServiceProvider serviceProvider)
    {
        try
        {
            InitializeComponent();

            _serviceProvider = serviceProvider ?? throw new ArgumentNullException(nameof(serviceProvider));
            _logger = serviceProvider.GetRequiredService<ILogger<AIModelConfigWindow>>();
            _configuration = serviceProvider.GetRequiredService<IConfiguration>();
            _toolApiConfigService = serviceProvider.GetRequiredService<IToolApiConfigService>();
            _customModelService = new CustomModelService(_logger as ILogger<CustomModelService> ??
                Microsoft.Extensions.Logging.Abstractions.NullLogger<CustomModelService>.Instance);
            _httpClient = new HttpClient();
            _httpClient.Timeout = TimeSpan.FromSeconds(10); // 设置超时时间

            // 延迟初始化UI和配置加载，确保所有控件都已加载
            this.Loaded += async (sender, e) => await SafeInitializeAsync();

            _logger.LogInformation("AI模型配置窗口构造函数完成");
        }
        catch (Exception ex)
        {
            _logger?.LogError(ex, "初始化AI模型配置窗口失败");
            MessageBox.Show($"初始化AI模型配置窗口失败：{ex.Message}", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
            throw;
        }
    }

    private async Task SafeInitializeAsync()
    {
        try
        {
            UpdateStatus("正在加载配置...");

            // 在后台线程加载配置
            _currentConfig = await Task.Run(() => LoadCurrentConfig());
            _currentToolApiConfig = await _toolApiConfigService.GetConfigAsync();

            // 加载自定义模型配置
            await _customModelService.LoadConfigAsync();

            // 在UI线程初始化界面
            await Dispatcher.InvokeAsync(() =>
            {
                InitializeUI();
                InitializeToolApiUI();
                LoadCustomModelsToUI();
            });

            UpdateStatus("配置加载完成");
            _logger.LogInformation("AI模型配置窗口初始化成功");
        }
        catch (Exception ex)
        {
            _logger?.LogError(ex, "安全初始化失败");
            UpdateStatus($"初始化失败: {ex.Message}");
            MessageBox.Show($"配置加载失败：{ex.Message}", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
        }
    }

    private bool ValidateUIElements()
    {
        try
        {
            // 检查基本配置UI元素
            if (TemperatureTextBox == null || MaxTokensTextBox == null ||
                EnableThinkingChainCheckBox == null || TimeoutTextBox == null)
            {
                return false;
            }

            // 检查平台选择UI元素
            if (OllamaRadio == null || LMStudioRadio == null ||
                ZhipuAIRadio == null || DeepSeekRadio == null)
            {
                return false;
            }

            // 检查状态显示元素
            if (StatusText == null)
            {
                return false;
            }

            return true;
        }
        catch (Exception ex)
        {
            _logger?.LogError(ex, "验证UI元素时发生错误");
            return false;
        }
    }

    private AIModelConfig CreateDefaultConfig()
    {
        return new AIModelConfig
        {
            Platform = "Ollama",
            Temperature = 0.7f,
            MaxTokens = 16384,
            EnableThinkingChain = true,
            EnableSegmentedGeneration = true,
            SegmentationThreshold = 3000,
            SegmentWordCount = 1500,
            Timeout = 30,
            OllamaConfig = new OllamaConfig { BaseUrl = "http://localhost:11434" },
            LMStudioConfig = new LMStudioConfig { BaseUrl = "http://localhost:1234" },
            ZhipuAIConfig = new ZhipuAIConfig
            {
                ApiKey = "",
                BaseUrl = "https://open.bigmodel.cn/api/paas/v4",
                Model = "GLM-4-Flash-250414"
            },
            DeepSeekConfig = new DeepSeekConfig
            {
                ApiKey = "",
                BaseUrl = "https://api.deepseek.com",
                Model = "deepseek-chat"
            },
            OpenAIConfig = new OpenAIConfig
            {
                ApiKey = "",
                BaseUrl = "https://api.openai.com/v1",
                Model = "gpt-3.5-turbo"
            },
            AlibabaConfig = new AlibabaConfig
            {
                ApiKey = "",
                BaseUrl = "https://dashscope.aliyuncs.com/api/v1",
                Model = "qwen-turbo"
            }
        };
    }

    private AIModelConfig LoadCurrentConfig()
    {
        try
        {
            // 首先尝试从配置服务加载保存的配置
            var configService = _serviceProvider.GetRequiredService<IAIModelConfigService>();
            var savedConfig = configService.GetConfigAsync().Result;

            if (savedConfig != null)
            {
                _logger?.LogInformation("从保存的配置文件加载AI配置");
                return savedConfig;
            }
        }
        catch (Exception ex)
        {
            _logger?.LogWarning(ex, "加载保存的配置失败，使用默认配置");
        }

        try
        {
            // 如果没有保存的配置，从appsettings.json加载
            var config = new AIModelConfig
            {
                Platform = _configuration?["AI:DefaultProvider"] ?? "Ollama",
                Temperature = 0.7f,
                MaxTokens = 2000,
                EnableThinkingChain = true,
                Timeout = 30
            };

            // 安全解析配置值
            if (float.TryParse(_configuration?["AI:DefaultTemperature"], out float temp))
            {
                config.Temperature = temp;
            }

            if (int.TryParse(_configuration?["AI:DefaultMaxTokens"], out int maxTokens))
            {
                config.MaxTokens = maxTokens;
            }

            if (bool.TryParse(_configuration?["AI:EnableThinkingChain"], out bool enableThinking))
            {
                config.EnableThinkingChain = enableThinking;
            }

            // 加载各平台配置
            config.OllamaConfig = new OllamaConfig
            {
                BaseUrl = _configuration?["AI:Ollama:BaseUrl"] ?? "http://localhost:11434"
            };

            config.LMStudioConfig = new LMStudioConfig
            {
                BaseUrl = _configuration?["AI:LMStudio:BaseUrl"] ?? "http://50844s9656.wocp.fun:42440"
            };

            config.ZhipuAIConfig = new ZhipuAIConfig
            {
                ApiKey = _configuration?["AI:ZhipuAI:ApiKey"] ?? "",
                BaseUrl = _configuration?["AI:ZhipuAI:BaseUrl"] ?? "https://open.bigmodel.cn/api/paas/v4",
                Model = _configuration?["AI:ZhipuAI:DefaultModel"] ?? "GLM-4-Flash-250414"
            };

            config.DeepSeekConfig = new DeepSeekConfig
            {
                ApiKey = _configuration?["AI:DeepSeek:ApiKey"] ?? "",
                BaseUrl = _configuration?["AI:DeepSeek:BaseUrl"] ?? "https://api.deepseek.com",
                Model = _configuration?["AI:DeepSeek:DefaultModel"] ?? "deepseek-chat"
            };

            return config;
        }
        catch (Exception ex)
        {
            _logger?.LogError(ex, "加载AI配置失败");
            // 返回默认配置
            return new AIModelConfig
            {
                Platform = "Ollama",
                Temperature = 0.7f,
                MaxTokens = 2000,
                EnableThinkingChain = true,
                Timeout = 30,
                OllamaConfig = new OllamaConfig { BaseUrl = "http://localhost:11434" },
                LMStudioConfig = new LMStudioConfig { BaseUrl = "http://localhost:1234" },
                ZhipuAIConfig = new ZhipuAIConfig
                {
                    ApiKey = "",
                    BaseUrl = "https://open.bigmodel.cn/api/paas/v4",
                    Model = "GLM-4-Flash-250414"
                },
                DeepSeekConfig = new DeepSeekConfig
                {
                    ApiKey = "",
                    BaseUrl = "https://api.deepseek.com",
                    Model = "deepseek-chat"
                },
                OpenAIConfig = new OpenAIConfig
                {
                    ApiKey = "",
                    BaseUrl = "https://api.openai.com/v1",
                    Model = "gpt-3.5-turbo"
                },
                AlibabaConfig = new AlibabaConfig
                {
                    ApiKey = "",
                    BaseUrl = "https://dashscope.aliyuncs.com/api/v1",
                    Model = "qwen-turbo"
                }
            };
        }
    }

    private void InitializeUI()
    {
        try
        {
            // 确保_currentConfig不为null
            if (_currentConfig == null)
            {
                _logger?.LogWarning("配置为空，使用默认配置");
                _currentConfig = CreateDefaultConfig();
            }

            // 检查关键UI元素是否已初始化
            if (!ValidateUIElements())
            {
                _logger?.LogWarning("UI元素尚未完全初始化，延迟重试");
                // 延迟重试
                Dispatcher.BeginInvoke(new Action(() => InitializeUI()), DispatcherPriority.Loaded);
                return;
            }

            // 设置当前配置值
            TemperatureTextBox.Text = _currentConfig.Temperature.ToString();
            MaxTokensTextBox.Text = _currentConfig.MaxTokens.ToString();
            EnableThinkingChainCheckBox.IsChecked = _currentConfig.EnableThinkingChain;
            EnableSegmentedGenerationCheckBox.IsChecked = _currentConfig.EnableSegmentedGeneration;
            SegmentationThresholdTextBox.Text = _currentConfig.SegmentationThreshold.ToString();
            SegmentWordCountTextBox.Text = _currentConfig.SegmentWordCount.ToString();
            TimeoutTextBox.Text = _currentConfig.Timeout.ToString();

            // 设置各平台配置，确保配置对象不为null
            if (_currentConfig.OllamaConfig != null && OllamaUrlTextBox != null)
            {
                OllamaUrlTextBox.Text = _currentConfig.OllamaConfig.BaseUrl ?? "http://localhost:11434";
            }
            else if (OllamaUrlTextBox != null)
            {
                OllamaUrlTextBox.Text = "http://localhost:11434";
            }

            if (_currentConfig.LMStudioConfig != null && LMStudioUrlTextBox != null)
            {
                LMStudioUrlTextBox.Text = _currentConfig.LMStudioConfig.BaseUrl ?? "http://localhost:1234";
            }
            else if (LMStudioUrlTextBox != null)
            {
                LMStudioUrlTextBox.Text = "http://localhost:1234";
            }

            if (_currentConfig.ZhipuAIConfig != null && ZhipuAPIKeyTextBox != null && ZhipuBaseUrlTextBox != null)
            {
                ZhipuAPIKeyTextBox.Text = _currentConfig.ZhipuAIConfig.ApiKey ?? "";
                ZhipuBaseUrlTextBox.Text = _currentConfig.ZhipuAIConfig.BaseUrl ?? "https://open.bigmodel.cn/api/paas/v4";
                if (ZhipuModelComboBox != null)
                {
                    SetModelSelection(_currentConfig.ZhipuAIConfig.Model ?? "GLM-4-Flash-250414", ZhipuModelComboBox);
                }
            }
            else if (ZhipuAPIKeyTextBox != null && ZhipuBaseUrlTextBox != null)
            {
                ZhipuAPIKeyTextBox.Text = "";
                ZhipuBaseUrlTextBox.Text = "https://open.bigmodel.cn/api/paas/v4";
                if (ZhipuModelComboBox != null)
                {
                    SetModelSelection("GLM-4-Flash-250414", ZhipuModelComboBox);
                }
            }

            if (_currentConfig.DeepSeekConfig != null && DeepSeekAPIKeyTextBox != null && DeepSeekBaseUrlTextBox != null)
            {
                DeepSeekAPIKeyTextBox.Text = _currentConfig.DeepSeekConfig.ApiKey ?? "";
                DeepSeekBaseUrlTextBox.Text = _currentConfig.DeepSeekConfig.BaseUrl ?? "https://api.deepseek.com";
                if (DeepSeekModelComboBox != null)
                {
                    SetModelSelection(_currentConfig.DeepSeekConfig.Model ?? "deepseek-chat", DeepSeekModelComboBox);
                }
            }
            else if (DeepSeekAPIKeyTextBox != null && DeepSeekBaseUrlTextBox != null)
            {
                DeepSeekAPIKeyTextBox.Text = "";
                DeepSeekBaseUrlTextBox.Text = "https://api.deepseek.com";
                if (DeepSeekModelComboBox != null)
                {
                    SetModelSelection("deepseek-chat", DeepSeekModelComboBox);
                }
            }

            // 初始化OpenAI配置
            if (_currentConfig.OpenAIConfig != null && OpenAIAPIKeyTextBox != null && OpenAIBaseUrlTextBox != null)
            {
                OpenAIAPIKeyTextBox.Text = _currentConfig.OpenAIConfig.ApiKey ?? "";
                OpenAIBaseUrlTextBox.Text = _currentConfig.OpenAIConfig.BaseUrl ?? "https://api.openai.com/v1";
                if (OpenAIModelComboBox != null)
                {
                    SetEditableModelSelection(_currentConfig.OpenAIConfig.Model ?? "gpt-3.5-turbo", OpenAIModelComboBox);
                }
            }
            else if (OpenAIAPIKeyTextBox != null && OpenAIBaseUrlTextBox != null)
            {
                OpenAIAPIKeyTextBox.Text = "";
                OpenAIBaseUrlTextBox.Text = "https://api.openai.com/v1";
                if (OpenAIModelComboBox != null)
                {
                    SetEditableModelSelection("gpt-3.5-turbo", OpenAIModelComboBox);
                }
            }

            // 初始化阿里模型配置
            if (_currentConfig.AlibabaConfig != null && AlibabaAPIKeyTextBox != null && AlibabaBaseUrlTextBox != null)
            {
                AlibabaAPIKeyTextBox.Text = _currentConfig.AlibabaConfig.ApiKey ?? "";
                AlibabaBaseUrlTextBox.Text = _currentConfig.AlibabaConfig.BaseUrl ?? "https://dashscope.aliyuncs.com/api/v1";
                if (AlibabaModelComboBox != null)
                {
                    SetModelSelection(_currentConfig.AlibabaConfig.Model ?? "qwen-turbo", AlibabaModelComboBox);
                }
            }
            else if (AlibabaAPIKeyTextBox != null && AlibabaBaseUrlTextBox != null)
            {
                AlibabaAPIKeyTextBox.Text = "";
                AlibabaBaseUrlTextBox.Text = "https://dashscope.aliyuncs.com/api/v1";
                if (AlibabaModelComboBox != null)
                {
                    SetModelSelection("qwen-turbo", AlibabaModelComboBox);
                }
            }

            // 初始化RWKV配置
            if (_currentConfig.RWKVConfig != null)
            {
                if (RWKVBaseUrlTextBox != null)
                    RWKVBaseUrlTextBox.Text = _currentConfig.RWKVConfig.BaseUrl ?? "http://localhost:8000";
                if (RWKVApiKeyTextBox != null)
                    RWKVApiKeyTextBox.Text = _currentConfig.RWKVConfig.ApiKey ?? "";
                if (RWKVModelComboBox != null)
                {
                    SetModelSelection(_currentConfig.RWKVConfig.SelectedModel ?? "RWKV-6-World-3B", RWKVModelComboBox);
                }
            }
            else
            {
                // 设置默认值
                if (RWKVBaseUrlTextBox != null)
                    RWKVBaseUrlTextBox.Text = "http://localhost:8000";
                if (RWKVModelComboBox != null)
                {
                    SetModelSelection("RWKV-6-World-3B", RWKVModelComboBox);
                }
            }

            // 设置平台选择
            if (OllamaRadio != null && LMStudioRadio != null && ZhipuAIRadio != null && DeepSeekRadio != null &&
                OpenAIRadio != null && AlibabaRadio != null && RWKVRadio != null)
            {
                SetPlatformSelection(_currentConfig.Platform ?? "Ollama");
            }

            UpdateStatus("配置已加载");
        }
        catch (Exception ex)
        {
            _logger?.LogError(ex, "初始化UI失败");
            UpdateStatus($"初始化UI失败: {ex.Message}");
        }
    }

    private void SetModelSelection(string model, ComboBox comboBox)
    {
        try
        {
            if (string.IsNullOrEmpty(model) || comboBox == null)
                return;

            foreach (ComboBoxItem item in comboBox.Items)
            {
                if (item?.Content?.ToString() == model)
                {
                    comboBox.SelectedItem = item;
                    item.IsSelected = true;
                    break;
                }
            }
        }
        catch (Exception ex)
        {
            _logger?.LogError(ex, $"设置模型选择失败: {model}");
        }
    }

    /// <summary>
    /// 设置可编辑ComboBox的模型选择，支持自定义模型名称
    /// </summary>
    private void SetEditableModelSelection(string model, ComboBox comboBox)
    {
        try
        {
            if (string.IsNullOrEmpty(model) || comboBox == null)
                return;

            // 首先尝试在预设项中查找匹配项
            foreach (ComboBoxItem item in comboBox.Items)
            {
                if (item?.Content?.ToString() == model)
                {
                    comboBox.SelectedItem = item;
                    return;
                }
            }

            // 如果没有找到匹配的预设项，直接设置文本（支持自定义模型名称）
            comboBox.Text = model;
        }
        catch (Exception ex)
        {
            _logger?.LogError(ex, $"设置可编辑模型选择失败: {model}");
        }
    }

    private void SetPlatformSelection(string platform)
    {
        try
        {
            if (string.IsNullOrEmpty(platform))
                platform = "Ollama";

            // 确保所有UI元素都已初始化
            if (OllamaRadio == null || LMStudioRadio == null || ZhipuAIRadio == null || DeepSeekRadio == null ||
                OpenAIRadio == null || AlibabaRadio == null || RWKVRadio == null)
            {
                _logger?.LogWarning("平台选择UI元素尚未初始化");
                return;
            }

            switch (platform.ToLower())
            {
                case "ollama":
                    OllamaRadio.IsChecked = true;
                    break;
                case "lmstudio":
                    LMStudioRadio.IsChecked = true;
                    break;
                case "zhipuai":
                    ZhipuAIRadio.IsChecked = true;
                    break;
                case "deepseek":
                    DeepSeekRadio.IsChecked = true;
                    break;
                case "openai":
                    OpenAIRadio.IsChecked = true;
                    break;
                case "alibaba":
                    AlibabaRadio.IsChecked = true;
                    break;
                case "rwkv":
                    RWKVRadio.IsChecked = true;
                    break;
                default:
                    OllamaRadio.IsChecked = true;
                    break;
            }

            // 手动触发平台切换逻辑，而不是调用事件处理器
            UpdatePlatformVisibility();
        }
        catch (Exception ex)
        {
            _logger?.LogError(ex, $"设置平台选择失败: {platform}");
        }
    }

    private void UpdatePlatformVisibility()
    {
        try
        {
            // 确保所有UI元素都已初始化
            if (OllamaConfig == null || LMStudioConfig == null || ZhipuAIConfig == null || DeepSeekConfig == null ||
                OpenAIConfig == null || AlibabaConfig == null || RWKVConfig == null ||
                PlatformTitle == null || PlatformDescription == null)
            {
                return;
            }

            // 隐藏所有配置面板
            OllamaConfig.Visibility = Visibility.Collapsed;
            LMStudioConfig.Visibility = Visibility.Collapsed;
            ZhipuAIConfig.Visibility = Visibility.Collapsed;
            DeepSeekConfig.Visibility = Visibility.Collapsed;
            OpenAIConfig.Visibility = Visibility.Collapsed;
            AlibabaConfig.Visibility = Visibility.Collapsed;
            RWKVConfig.Visibility = Visibility.Collapsed;

            // 显示选中的配置面板
            if (OllamaRadio?.IsChecked == true)
            {
                PlatformTitle.Text = "Ollama 配置";
                PlatformDescription.Text = "本地开源AI模型平台，免费使用，需要本地安装";
                OllamaConfig.Visibility = Visibility.Visible;
            }
            else if (LMStudioRadio?.IsChecked == true)
            {
                PlatformTitle.Text = "LM Studio 配置";
                PlatformDescription.Text = "本地AI模型运行环境，提供图形界面管理";
                LMStudioConfig.Visibility = Visibility.Visible;
            }
            else if (ZhipuAIRadio?.IsChecked == true)
            {
                PlatformTitle.Text = "智谱AI 配置";
                PlatformDescription.Text = "智谱AI云端服务，支持多模态AI能力";
                ZhipuAIConfig.Visibility = Visibility.Visible;
            }
            else if (DeepSeekRadio?.IsChecked == true)
            {
                PlatformTitle.Text = "DeepSeek 配置";
                PlatformDescription.Text = "DeepSeek云端服务，高质量对话和代码生成";
                DeepSeekConfig.Visibility = Visibility.Visible;
            }
            else if (OpenAIRadio?.IsChecked == true)
            {
                PlatformTitle.Text = "OpenAI 自定义配置";
                PlatformDescription.Text = "OpenAI官方API或兼容接口，支持GPT系列模型";
                OpenAIConfig.Visibility = Visibility.Visible;
            }
            else if (AlibabaRadio?.IsChecked == true)
            {
                PlatformTitle.Text = "阿里模型配置";
                PlatformDescription.Text = "阿里云通义千问系列模型，支持多模态AI能力";
                AlibabaConfig.Visibility = Visibility.Visible;
            }
            else if (RWKVRadio?.IsChecked == true)
            {
                PlatformTitle.Text = "RWKV 配置";
                PlatformDescription.Text = "RWKV开源大语言模型，支持本地部署和API调用";
                RWKVConfig.Visibility = Visibility.Visible;
            }
        }
        catch (Exception ex)
        {
            _logger?.LogError(ex, "更新平台可见性失败");
        }
    }

    private void Platform_Checked(object sender, RoutedEventArgs e)
    {
        UpdatePlatformVisibility();
    }

    private async void DetectModels_Click(object sender, RoutedEventArgs e)
    {
        try
        {
            UpdateStatus("正在检测模型...", true);

            if (OllamaRadio.IsChecked == true)
            {
                await DetectOllamaModels();
            }
            else if (LMStudioRadio.IsChecked == true)
            {
                await DetectLMStudioModels();
            }

            UpdateStatus("模型检测完成", false);
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "检测模型失败");
            UpdateStatus($"检测失败: {ex.Message}", false);
        }
    }

    private async Task DetectOllamaModels()
    {
        var url = OllamaUrlTextBox.Text.TrimEnd('/') + "/api/tags";

        try
        {
            using var cts = new CancellationTokenSource(TimeSpan.FromSeconds(10));
            var response = await _httpClient.GetStringAsync(url, cts.Token);

            var options = new JsonSerializerOptions
            {
                PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
                PropertyNameCaseInsensitive = true
            };

            var result = JsonSerializer.Deserialize<OllamaModelsResponse>(response, options);

            OllamaModelComboBox.Items.Clear();

            if (result?.Models != null)
            {
                foreach (var model in result.Models)
                {
                    var aiModel = new AIModel
                    {
                        Id = model.Name,
                        Name = $"{model.Name} ({FormatSize(model.Size)})",
                        Provider = "Ollama",
                        IsAvailable = true
                    };
                    OllamaModelComboBox.Items.Add(aiModel);
                }

                if (OllamaModelComboBox.Items.Count > 0)
                {
                    OllamaModelComboBox.SelectedIndex = 0;
                }
            }
        }
        catch (Exception ex)
        {
            throw new Exception($"无法连接到Ollama服务: {ex.Message}");
        }
    }

    private async Task DetectLMStudioModels()
    {
        var url = LMStudioUrlTextBox.Text.TrimEnd('/') + "/v1/models";

        try
        {
            using var cts = new CancellationTokenSource(TimeSpan.FromSeconds(10));
            var response = await _httpClient.GetStringAsync(url, cts.Token);

            var options = new JsonSerializerOptions
            {
                PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
                PropertyNameCaseInsensitive = true
            };

            var result = JsonSerializer.Deserialize<LMStudioModelsResponse>(response, options);

            LMStudioModelComboBox.Items.Clear();

            if (result?.Data != null)
            {
                foreach (var model in result.Data)
                {
                    var aiModel = new AIModel
                    {
                        Id = model.Id,
                        Name = $"{model.Id} ({model.OwnedBy})",
                        Provider = "LMStudio",
                        IsAvailable = true
                    };
                    LMStudioModelComboBox.Items.Add(aiModel);
                }

                if (LMStudioModelComboBox.Items.Count > 0)
                {
                    LMStudioModelComboBox.SelectedIndex = 0;
                }
            }
        }
        catch (Exception ex)
        {
            throw new Exception($"无法连接到LM Studio服务: {ex.Message}");
        }
    }

    private async void TestConnection_Click(object sender, RoutedEventArgs e)
    {
        try
        {
            string platformName = "";
            string modelName = "";

            // 获取当前选择的平台和模型信息
            if (OllamaRadio.IsChecked == true)
            {
                platformName = "Ollama";
                modelName = (OllamaModelComboBox?.SelectedItem as AIModel)?.Name ?? "未选择模型";
            }
            else if (LMStudioRadio.IsChecked == true)
            {
                platformName = "LMStudio";
                modelName = (LMStudioModelComboBox?.SelectedItem as AIModel)?.Name ?? "未选择模型";
            }
            else if (ZhipuAIRadio.IsChecked == true)
            {
                platformName = "ZhipuAI";
                modelName = GetSelectedModelName(ZhipuModelComboBox) ?? "GLM-4-Flash-250414";
            }
            else if (DeepSeekRadio.IsChecked == true)
            {
                platformName = "DeepSeek";
                modelName = GetSelectedModelName(DeepSeekModelComboBox) ?? "deepseek-chat";
            }
            else if (OpenAIRadio.IsChecked == true)
            {
                platformName = "OpenAI";
                modelName = GetSelectedModelName(OpenAIModelComboBox) ?? "gpt-3.5-turbo";
            }
            else if (AlibabaRadio.IsChecked == true)
            {
                platformName = "Alibaba";
                modelName = GetSelectedModelName(AlibabaModelComboBox) ?? "qwen-turbo";
            }

            UpdateStatus($"正在测试 {platformName} - {modelName} 连接...", true);
            TestConnectionButton.IsEnabled = false;

            // 构建当前配置用于测试
            var testConfig = BuildConfigFromUI();

            // 使用统一的测试方法
            var configService = _serviceProvider.GetRequiredService<IAIModelConfigService>();
            await configService.TestConnectionAsync(testConfig);

            UpdateStatus($"{platformName} - {modelName} 连接测试成功！正在保存配置...", true);

            // 测试成功后自动保存配置
            await AutoSaveConfigAfterTest();

            UpdateStatus($"{platformName} - {modelName} 配置已保存并应用", false);
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "连接测试失败");
            UpdateStatus($"连接失败: {ex.Message}", false);
        }
        finally
        {
            TestConnectionButton.IsEnabled = true;
        }
    }

    private async Task AutoSaveConfigAfterTest()
    {
        try
        {
            // 构建配置
            var config = BuildConfigFromUI();

            // 保存配置到服务
            var configService = _serviceProvider.GetRequiredService<IAIModelConfigService>();
            await configService.SaveConfigAsync(config);

            // 设置结果
            Result = config;

            // 通知主窗口重新加载AI服务配置
            await NotifyConfigurationChanged(config);

            // 显示成功消息
            var result = MessageBox.Show(
                "连接测试成功！配置已自动保存并应用。\n\n是否关闭配置窗口？",
                "测试成功",
                MessageBoxButton.YesNo,
                MessageBoxImage.Information);

            if (result == MessageBoxResult.Yes)
            {
                DialogResult = true;
                Close();
            }
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "自动保存配置失败");
            UpdateStatus($"保存配置失败: {ex.Message}");
            throw;
        }
    }

    /// <summary>
    /// 通知配置已更改，重新加载AI服务
    /// </summary>
    private async Task NotifyConfigurationChanged(AIModelConfig config)
    {
        try
        {
            // 获取AI服务管理器
            var aiService = _serviceProvider.GetService<IAIService>();
            if (aiService is AIServiceManager aiServiceManager)
            {
                await aiServiceManager.ReloadConfigurationAsync();
                _logger.LogInformation("AI服务配置已重新加载");
            }
        }
        catch (Exception ex)
        {
            _logger.LogWarning(ex, "重新加载AI服务配置失败");
            // 不抛出异常，因为配置已经保存成功
        }
    }

    private async Task TestOllamaConnection()
    {
        var baseUrl = OllamaUrlTextBox.Text.TrimEnd('/');
        var selectedModel = (OllamaModelComboBox?.SelectedItem as AIModel)?.Id;

        // 首先测试服务器连接
        var url = baseUrl + "/api/tags";
        using var cts = new CancellationTokenSource(TimeSpan.FromSeconds(10));
        var response = await _httpClient.GetStringAsync(url, cts.Token);

        // 如果选择了模型，测试模型是否可用
        if (!string.IsNullOrEmpty(selectedModel))
        {
            var testRequest = new
            {
                model = selectedModel,
                prompt = "测试连接",
                stream = false
            };

            var json = JsonSerializer.Serialize(testRequest);
            var content = new StringContent(json, System.Text.Encoding.UTF8, "application/json");
            var testResponse = await _httpClient.PostAsync($"{baseUrl}/api/generate", content);

            if (!testResponse.IsSuccessStatusCode)
            {
                throw new Exception($"模型 {selectedModel} 不可用");
            }
        }
    }

    private async Task TestLMStudioConnection()
    {
        var baseUrl = LMStudioUrlTextBox.Text.TrimEnd('/');
        var selectedModel = (LMStudioModelComboBox?.SelectedItem as AIModel)?.Id;

        // 测试服务器连接
        var url = baseUrl + "/v1/models";
        var response = await _httpClient.GetStringAsync(url);

        // 如果选择了模型，验证模型在可用列表中
        if (!string.IsNullOrEmpty(selectedModel))
        {
            var modelsResponse = JsonSerializer.Deserialize<JsonElement>(response);
            if (modelsResponse.TryGetProperty("data", out var dataElement))
            {
                var modelFound = false;
                foreach (var model in dataElement.EnumerateArray())
                {
                    if (model.TryGetProperty("id", out var idElement) &&
                        idElement.GetString() == selectedModel)
                    {
                        modelFound = true;
                        break;
                    }
                }

                if (!modelFound)
                {
                    throw new Exception($"模型 {selectedModel} 在LM Studio中不可用");
                }
            }
        }
    }

    private async Task TestZhipuAIConnection()
    {
        if (string.IsNullOrWhiteSpace(ZhipuAPIKeyTextBox.Text))
        {
            throw new Exception("请输入智谱AI API Key");
        }

        var selectedModel = (ZhipuModelComboBox.SelectedItem as ComboBoxItem)?.Content.ToString() ?? "GLM-4-Flash-250414";

        try
        {
            var baseUrl = ZhipuBaseUrlTextBox.Text.TrimEnd('/');
            var url = $"{baseUrl}/chat/completions";

            var request = new
            {
                model = selectedModel,
                messages = new[]
                {
                    new { role = "user", content = "测试连接" }
                },
                max_tokens = 10,
                temperature = 0.1
            };

            var json = JsonSerializer.Serialize(request);
            var content = new StringContent(json, System.Text.Encoding.UTF8, "application/json");

            _httpClient.DefaultRequestHeaders.Clear();
            _httpClient.DefaultRequestHeaders.Add("Authorization", $"Bearer {ZhipuAPIKeyTextBox.Text}");

            var response = await _httpClient.PostAsync(url, content);
            if (!response.IsSuccessStatusCode)
            {
                var errorContent = await response.Content.ReadAsStringAsync();
                var errorMessage = $"智谱AI API调用失败 (模型: {selectedModel}): {response.StatusCode}";

                // 尝试解析错误详情
                try
                {
                    var errorJson = JsonSerializer.Deserialize<JsonElement>(errorContent);
                    if (errorJson.TryGetProperty("error", out var errorElement) &&
                        errorElement.TryGetProperty("message", out var messageElement))
                    {
                        errorMessage += $" - {messageElement.GetString()}";
                    }
                }
                catch
                {
                    errorMessage += $" - {errorContent}";
                }

                throw new Exception(errorMessage);
            }

            // 验证响应格式
            var responseContent = await response.Content.ReadAsStringAsync();
            var responseJson = JsonSerializer.Deserialize<JsonElement>(responseContent);
            if (!responseJson.TryGetProperty("choices", out _))
            {
                throw new Exception($"智谱AI响应格式异常 (模型: {selectedModel})");
            }
        }
        catch (HttpRequestException ex)
        {
            throw new Exception($"智谱AI网络连接失败 (模型: {selectedModel}): {ex.Message}");
        }
        catch (Exception ex) when (!(ex is HttpRequestException))
        {
            if (ex.Message.Contains("智谱AI"))
            {
                throw; // 重新抛出已经格式化的异常
            }
            throw new Exception($"智谱AI连接测试失败 (模型: {selectedModel}): {ex.Message}");
        }
    }

    private async Task TestDeepSeekConnection()
    {
        if (string.IsNullOrWhiteSpace(DeepSeekAPIKeyTextBox.Text))
        {
            throw new Exception("请输入DeepSeek API Key");
        }

        var selectedModel = (DeepSeekModelComboBox.SelectedItem as ComboBoxItem)?.Content.ToString() ?? "deepseek-chat";

        try
        {
            var baseUrl = DeepSeekBaseUrlTextBox.Text.TrimEnd('/');
            var url = $"{baseUrl}/chat/completions";

            var request = new
            {
                model = selectedModel,
                messages = new[]
                {
                    new { role = "user", content = "测试连接" }
                },
                max_tokens = 10,
                temperature = 0.1
            };

            var json = JsonSerializer.Serialize(request);
            var content = new StringContent(json, System.Text.Encoding.UTF8, "application/json");

            _httpClient.DefaultRequestHeaders.Clear();
            _httpClient.DefaultRequestHeaders.Add("Authorization", $"Bearer {DeepSeekAPIKeyTextBox.Text}");

            var response = await _httpClient.PostAsync(url, content);
            if (!response.IsSuccessStatusCode)
            {
                var errorContent = await response.Content.ReadAsStringAsync();
                var errorMessage = $"DeepSeek API调用失败 (模型: {selectedModel}): {response.StatusCode}";

                // 尝试解析错误详情
                try
                {
                    var errorJson = JsonSerializer.Deserialize<JsonElement>(errorContent);
                    if (errorJson.TryGetProperty("error", out var errorElement))
                    {
                        if (errorElement.TryGetProperty("message", out var messageElement))
                        {
                            errorMessage += $" - {messageElement.GetString()}";
                        }
                        else if (errorElement.TryGetProperty("type", out var typeElement))
                        {
                            errorMessage += $" - {typeElement.GetString()}";
                        }
                    }
                }
                catch
                {
                    errorMessage += $" - {errorContent}";
                }

                throw new Exception(errorMessage);
            }

            // 验证响应格式
            var responseContent = await response.Content.ReadAsStringAsync();
            var responseJson = JsonSerializer.Deserialize<JsonElement>(responseContent);
            if (!responseJson.TryGetProperty("choices", out _))
            {
                throw new Exception($"DeepSeek响应格式异常 (模型: {selectedModel})");
            }
        }
        catch (HttpRequestException ex)
        {
            throw new Exception($"DeepSeek网络连接失败 (模型: {selectedModel}): {ex.Message}");
        }
        catch (Exception ex) when (!(ex is HttpRequestException))
        {
            if (ex.Message.Contains("DeepSeek"))
            {
                throw; // 重新抛出已经格式化的异常
            }
            throw new Exception($"DeepSeek连接测试失败 (模型: {selectedModel}): {ex.Message}");
        }
    }

    private void RefreshModels_Click(object sender, RoutedEventArgs e)
    {
        DetectModels_Click(sender, e);
    }

    private async void Save_Click(object sender, RoutedEventArgs e)
    {
        try
        {
            UpdateStatus("正在保存配置...");

            // 保存AI模型配置
            Result = BuildConfigFromUI();

            // 保存工具API配置
            var toolApiConfig = GetCurrentToolApiConfig();
            var (success, message) = await _toolApiConfigService.SaveConfigAsync(toolApiConfig);

            if (!success)
            {
                UpdateStatus($"保存工具API配置失败: {message}");
                MessageBox.Show($"保存工具API配置失败: {message}", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
                return;
            }

            // 检查工具可用性并提示用户
            var availability = toolApiConfig.GetToolAvailability();
            var disabledTools = new List<string>();

            if (!availability.IsSearchEnabled) disabledTools.Add("搜索");
            if (!availability.IsTranslateEnabled) disabledTools.Add("翻译");
            if (!availability.IsWeatherEnabled) disabledTools.Add("天气");
            if (!availability.IsNewsEnabled) disabledTools.Add("新闻");

            if (disabledTools.Count > 0)
            {
                var disabledToolsText = string.Join("、", disabledTools);
                UpdateStatus($"配置已保存，但以下工具因缺少APIkey而被禁用: {disabledToolsText}");
            }

            UpdateStatus("配置保存成功");
            DialogResult = true;
            Close();
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "保存配置失败");
            UpdateStatus($"保存失败: {ex.Message}");
            MessageBox.Show($"保存配置失败: {ex.Message}", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
        }
    }

    private void Cancel_Click(object sender, RoutedEventArgs e)
    {
        DialogResult = false;
        Close();
    }

    private AIModelConfig BuildConfigFromUI()
    {
        var config = new AIModelConfig();

        // 验证和设置基本参数
        if (!float.TryParse(TemperatureTextBox.Text, out float temperature) || temperature < 0 || temperature > 2)
        {
            throw new ArgumentException("温度值必须在0-2之间");
        }
        if (!int.TryParse(MaxTokensTextBox.Text, out int maxTokens) || maxTokens < 1 || maxTokens > 100000)
        {
            throw new ArgumentException("最大令牌数必须在1-100000之间");
        }
        if (!int.TryParse(TimeoutTextBox.Text, out int timeout) || timeout < 5 || timeout > 300)
        {
            throw new ArgumentException("超时时间必须在5-300秒之间");
        }

        // 验证分段生成配置
        if (!int.TryParse(SegmentationThresholdTextBox.Text, out int segmentationThreshold) || segmentationThreshold < 1000 || segmentationThreshold > 10000)
        {
            throw new ArgumentException("分段生成阈值必须在1000-10000字之间");
        }
        if (!int.TryParse(SegmentWordCountTextBox.Text, out int segmentWordCount) || segmentWordCount < 500 || segmentWordCount > 3000)
        {
            throw new ArgumentException("每段字数必须在500-3000字之间");
        }

        config.Temperature = temperature;
        config.MaxTokens = maxTokens;
        config.EnableThinkingChain = EnableThinkingChainCheckBox.IsChecked ?? true;
        config.EnableSegmentedGeneration = EnableSegmentedGenerationCheckBox.IsChecked ?? true;
        config.SegmentationThreshold = segmentationThreshold;
        config.SegmentWordCount = segmentWordCount;
        config.Timeout = timeout;

        // 保存所有平台的配置（不仅仅是当前选中的）
        config.OllamaConfig = new OllamaConfig
        {
            BaseUrl = OllamaUrlTextBox?.Text?.Trim() ?? "http://localhost:11434",
            SelectedModel = (OllamaModelComboBox?.SelectedItem as AIModel)?.Id ?? ""
        };

        config.LMStudioConfig = new LMStudioConfig
        {
            BaseUrl = LMStudioUrlTextBox?.Text?.Trim() ?? "http://50844s9656.wocp.fun:42440",
            SelectedModel = GetLMStudioSelectedModel()
        };

        config.ZhipuAIConfig = new ZhipuAIConfig
        {
            ApiKey = ZhipuAPIKeyTextBox?.Text?.Trim() ?? "",
            BaseUrl = ZhipuBaseUrlTextBox?.Text?.Trim() ?? "https://open.bigmodel.cn/api/paas/v4",
            Model = GetSelectedModelName(ZhipuModelComboBox) ?? "GLM-4-Flash-250414"
        };

        config.DeepSeekConfig = new DeepSeekConfig
        {
            ApiKey = DeepSeekAPIKeyTextBox?.Text?.Trim() ?? "",
            BaseUrl = DeepSeekBaseUrlTextBox?.Text?.Trim() ?? "https://api.deepseek.com",
            Model = GetSelectedModelName(DeepSeekModelComboBox) ?? "deepseek-chat"
        };

        config.OpenAIConfig = new OpenAIConfig
        {
            ApiKey = OpenAIAPIKeyTextBox?.Text?.Trim() ?? "",
            BaseUrl = OpenAIBaseUrlTextBox?.Text?.Trim() ?? "https://api.openai.com/v1",
            Model = GetSelectedModelName(OpenAIModelComboBox) ?? "gpt-3.5-turbo"
        };

        config.AlibabaConfig = new AlibabaConfig
        {
            ApiKey = AlibabaAPIKeyTextBox?.Text?.Trim() ?? "",
            BaseUrl = AlibabaBaseUrlTextBox?.Text?.Trim() ?? "https://dashscope.aliyuncs.com/api/v1",
            Model = GetSelectedModelName(AlibabaModelComboBox) ?? "qwen-turbo"
        };

        config.RWKVConfig = new RWKVConfig
        {
            BaseUrl = RWKVBaseUrlTextBox?.Text?.Trim() ?? "http://localhost:8000",
            ApiKey = RWKVApiKeyTextBox?.Text?.Trim() ?? "",
            SelectedModel = GetSelectedModelName(RWKVModelComboBox) ?? ""
        };

        // 设置当前选中的平台并进行验证
        if (OllamaRadio?.IsChecked == true)
        {
            if (string.IsNullOrWhiteSpace(config.OllamaConfig.BaseUrl))
                throw new ArgumentException("请输入Ollama服务地址");
            if (!Uri.TryCreate(config.OllamaConfig.BaseUrl, UriKind.Absolute, out _))
                throw new ArgumentException("Ollama服务地址格式不正确");

            config.Platform = "Ollama";
        }
        else if (LMStudioRadio?.IsChecked == true)
        {
            if (string.IsNullOrWhiteSpace(config.LMStudioConfig.BaseUrl))
                throw new ArgumentException("请输入LM Studio服务地址");
            if (!Uri.TryCreate(config.LMStudioConfig.BaseUrl, UriKind.Absolute, out _))
                throw new ArgumentException("LM Studio服务地址格式不正确");

            config.Platform = "LMStudio";
        }
        else if (ZhipuAIRadio?.IsChecked == true)
        {
            if (string.IsNullOrWhiteSpace(config.ZhipuAIConfig.ApiKey))
                throw new ArgumentException("请输入智谱AI的API Key");
            if (string.IsNullOrWhiteSpace(config.ZhipuAIConfig.BaseUrl))
                throw new ArgumentException("请输入智谱AI的服务地址");
            if (!Uri.TryCreate(config.ZhipuAIConfig.BaseUrl, UriKind.Absolute, out _))
                throw new ArgumentException("智谱AI服务地址格式不正确");

            config.Platform = "ZhipuAI";
        }
        else if (DeepSeekRadio?.IsChecked == true)
        {
            if (string.IsNullOrWhiteSpace(config.DeepSeekConfig.ApiKey))
                throw new ArgumentException("请输入DeepSeek的API Key");
            if (string.IsNullOrWhiteSpace(config.DeepSeekConfig.BaseUrl))
                throw new ArgumentException("请输入DeepSeek的服务地址");
            if (!Uri.TryCreate(config.DeepSeekConfig.BaseUrl, UriKind.Absolute, out _))
                throw new ArgumentException("DeepSeek服务地址格式不正确");

            config.Platform = "DeepSeek";
        }
        else if (OpenAIRadio?.IsChecked == true)
        {
            // API Key对于本地模型是可选的
            if (string.IsNullOrWhiteSpace(config.OpenAIConfig.BaseUrl))
                throw new ArgumentException("请输入OpenAI的服务地址");
            if (!Uri.TryCreate(config.OpenAIConfig.BaseUrl, UriKind.Absolute, out _))
                throw new ArgumentException("OpenAI服务地址格式不正确");

            config.Platform = "OpenAI";
        }
        else if (AlibabaRadio?.IsChecked == true)
        {
            if (string.IsNullOrWhiteSpace(config.AlibabaConfig.ApiKey))
                throw new ArgumentException("请输入阿里云的API Key");
            if (string.IsNullOrWhiteSpace(config.AlibabaConfig.BaseUrl))
                throw new ArgumentException("请输入阿里云的服务地址");
            if (!Uri.TryCreate(config.AlibabaConfig.BaseUrl, UriKind.Absolute, out _))
                throw new ArgumentException("阿里云服务地址格式不正确");

            config.Platform = "Alibaba";
        }
        else if (RWKVRadio?.IsChecked == true)
        {
            if (string.IsNullOrWhiteSpace(config.RWKVConfig.BaseUrl))
                throw new ArgumentException("请输入RWKV Runner服务地址");
            if (!Uri.TryCreate(config.RWKVConfig.BaseUrl, UriKind.Absolute, out _))
                throw new ArgumentException("RWKV Runner服务地址格式不正确");



            config.Platform = "RWKV";
        }
        else
        {
            throw new ArgumentException("请选择一个AI平台");
        }
        
        return config;
    }

    /// <summary>
    /// 获取LM Studio选中的模型，优先使用ComboBox选中项，如果为空则使用配置中的值
    /// </summary>
    private string GetLMStudioSelectedModel()
    {
        // 优先使用ComboBox中的选中项
        var selectedFromComboBox = (LMStudioModelComboBox?.SelectedItem as AIModel)?.Id;
        if (!string.IsNullOrEmpty(selectedFromComboBox))
        {
            return selectedFromComboBox;
        }

        // 如果ComboBox为空，使用当前配置中的值
        var configuredModel = _currentConfig?.LMStudioConfig?.SelectedModel;
        if (!string.IsNullOrEmpty(configuredModel))
        {
            return configuredModel;
        }

        return "";
    }

    /// <summary>
    /// 获取OpenAI选中的模型，支持可编辑ComboBox的文本输入
    /// </summary>
    private string GetOpenAISelectedModel()
    {
        // 优先使用ComboBox中的文本（支持用户输入的自定义模型名称）
        var textValue = OpenAIModelComboBox?.Text?.Trim();
        if (!string.IsNullOrEmpty(textValue))
        {
            return textValue;
        }

        // 如果文本为空，尝试获取选中项的内容
        var selectedFromComboBox = (OpenAIModelComboBox?.SelectedItem as ComboBoxItem)?.Content?.ToString();
        if (!string.IsNullOrEmpty(selectedFromComboBox))
        {
            return selectedFromComboBox;
        }

        // 如果ComboBox为空，使用当前配置中的值
        var configuredModel = _currentConfig?.OpenAIConfig?.Model;
        if (!string.IsNullOrEmpty(configuredModel))
        {
            return configuredModel;
        }

        return "gpt-3.5-turbo";
    }

    private void UpdateStatus(string message, bool showProgress = false)
    {
        try
        {
            if (StatusText != null)
            {
                StatusText.Text = message ?? "就绪";
            }

            if (StatusProgressBar != null)
            {
                StatusProgressBar.Visibility = showProgress ? Visibility.Visible : Visibility.Collapsed;
                StatusProgressBar.IsIndeterminate = showProgress;
            }
        }
        catch (Exception ex)
        {
            _logger?.LogError(ex, "更新状态失败");
        }
    }

    private string FormatSize(long bytes)
    {
        string[] sizes = { "B", "KB", "MB", "GB", "TB" };
        double len = bytes;
        int order = 0;
        while (len >= 1024 && order < sizes.Length - 1)
        {
            order++;
            len = len / 1024;
        }
        return $"{len:0.##} {sizes[order]}";
    }
}

// 响应模型类
public class OllamaModelsResponse
{
    public List<OllamaModelInfo> Models { get; set; } = new();
}

public class OllamaModelInfo
{
    public string Name { get; set; } = "";
    public long Size { get; set; }
    [JsonPropertyName("modified_at")]
    public DateTime ModifiedAt { get; set; }
}

public class LMStudioModelsResponse
{
    public List<LMStudioModelInfo> Data { get; set; } = new();
}

public class LMStudioModelInfo
{
    public string Id { get; set; } = "";
    public string Object { get; set; } = "";
    public long Created { get; set; }
    [JsonPropertyName("owned_by")]
    public string OwnedBy { get; set; } = "";
}

/// <summary>
/// 模型下载事件处理
/// </summary>
partial class AIModelConfigWindow
{
    private async void DownloadModel_Click(object sender, RoutedEventArgs e)
    {
        if (sender is Button button && button.Tag is string modelName)
        {
            await DownloadOllamaModelAsync(modelName);
        }
    }

    private async void DownloadCustomModel_Click(object sender, RoutedEventArgs e)
    {
        var modelName = CustomModelTextBox.Text?.Trim();
        if (string.IsNullOrEmpty(modelName))
        {
            UpdateStatus("请输入模型名称", false);
            return;
        }

        await DownloadOllamaModelAsync(modelName);
    }

    /// <summary>
    /// 打开Ollama模型下载对话框
    /// </summary>
    private void DownloadOllamaModel_Click(object sender, RoutedEventArgs e)
    {
        try
        {
            var downloadDialog = new OllamaModelDownloadDialog
            {
                Owner = this
            };

            // 设置当前的Ollama URL
            var ollamaUrl = OllamaUrlTextBox.Text?.Trim();
            if (!string.IsNullOrEmpty(ollamaUrl))
            {
                downloadDialog.SetOllamaUrl(ollamaUrl);
            }

            var result = downloadDialog.ShowDialog();

            // 如果下载成功，刷新模型列表
            if (result == true)
            {
                DetectModels_Click(sender, e);
                UpdateStatus("模型下载完成，已刷新模型列表", false);
            }
        }
        catch (Exception ex)
        {
            _logger?.LogError(ex, "打开模型下载对话框失败");
            UpdateStatus($"打开下载对话框失败: {ex.Message}", false);
        }
    }

    private async Task DownloadOllamaModelAsync(string modelName)
    {
        try
        {
            UpdateStatus($"正在下载模型: {modelName}...", true);
            DownloadStatusText.Text = $"正在下载 {modelName}...";
            DownloadProgressBar.Visibility = Visibility.Visible;
            DownloadProgressBar.IsIndeterminate = true;

            var ollamaUrl = OllamaUrlTextBox.Text?.Trim() ?? "http://localhost:11434";
            var pullUrl = $"{ollamaUrl}/api/pull";

            var requestBody = new { name = modelName };
            var json = JsonSerializer.Serialize(requestBody);
            var content = new StringContent(json, System.Text.Encoding.UTF8, "application/json");

            using var httpClient = new HttpClient();
            httpClient.Timeout = TimeSpan.FromMinutes(30); // 下载可能需要很长时间

            var response = await httpClient.PostAsync(pullUrl, content);

            if (response.IsSuccessStatusCode)
            {
                UpdateStatus($"模型 {modelName} 下载成功！", false);
                DownloadStatusText.Text = $"模型 {modelName} 下载完成";

                // 下载成功后刷新模型列表
                DetectModels_Click(null!, null!);
            }
            else
            {
                var errorContent = await response.Content.ReadAsStringAsync();
                UpdateStatus($"下载失败: {response.StatusCode}", false);
                DownloadStatusText.Text = $"下载失败: {errorContent}";
            }
        }
        catch (Exception ex)
        {
            _logger?.LogError(ex, $"下载模型失败: {modelName}");
            UpdateStatus($"下载失败: {ex.Message}", false);
            DownloadStatusText.Text = $"下载失败: {ex.Message}";
        }
        finally
        {
            DownloadProgressBar.Visibility = Visibility.Collapsed;
            DownloadProgressBar.IsIndeterminate = false;
        }
    }

    #region 工具API配置相关方法

    /// <summary>
    /// 初始化工具API配置UI
    /// </summary>
    private void InitializeToolApiUI()
    {
        try
        {
            if (_currentToolApiConfig == null)
            {
                _logger.LogWarning("工具API配置为空，使用默认配置");
                return;
            }

            // 初始化搜索API配置
            InitializeSearchApiUI();

            // 初始化翻译API配置
            InitializeTranslateApiUI();

            // 初始化其他API配置
            InitializeOtherApiUI();

            // 设置单选按钮事件
            SetupToolApiEvents();

            // 更新工具状态指示器
            UpdateToolStatusIndicators(_currentToolApiConfig);

            _logger.LogInformation("工具API配置UI初始化完成");
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "初始化工具API配置UI失败");
        }
    }

    /// <summary>
    /// 初始化搜索API配置UI
    /// </summary>
    private void InitializeSearchApiUI()
    {
        var searchConfig = _currentToolApiConfig.SearchConfig;

        // 设置搜索引擎选择
        switch (searchConfig.SearchEngine.ToLower())
        {
            case "google":
                GoogleSearchRadio.IsChecked = true;
                break;
            case "bing":
                BingSearchRadio.IsChecked = true;
                break;
            case "serper":
                SerperSearchRadio.IsChecked = true;
                break;
        }

        // 设置Google搜索配置
        GoogleApiKeyTextBox.Text = searchConfig.GoogleConfig.ApiKey;
        GoogleSearchEngineIdTextBox.Text = searchConfig.GoogleConfig.SearchEngineId;

        // 设置Bing搜索配置
        BingApiKeyTextBox.Text = searchConfig.BingConfig.ApiKey;

        // 设置Serper搜索配置
        SerperApiKeyTextBox.Text = searchConfig.SerperConfig.ApiKey;

        // 设置搜索设置
        SearchResultCountTextBox.Text = searchConfig.ResultCount.ToString();
        SearchLanguageTextBox.Text = searchConfig.Language;
        SafeSearchCheckBox.IsChecked = searchConfig.SafeSearch;

        // 显示对应的配置面板
        UpdateSearchConfigVisibility();
    }

    /// <summary>
    /// 初始化翻译API配置UI
    /// </summary>
    private void InitializeTranslateApiUI()
    {
        var translateConfig = _currentToolApiConfig.TranslateConfig;

        // 设置翻译服务选择
        switch (translateConfig.TranslateService.ToLower())
        {
            case "google":
                GoogleTranslateRadio.IsChecked = true;
                break;
            case "baidu":
                BaiduTranslateRadio.IsChecked = true;
                break;
            case "tencent":
                TencentTranslateRadio.IsChecked = true;
                break;
        }

        // 设置Google翻译配置
        GoogleTranslateApiKeyTextBox.Text = translateConfig.GoogleConfig.ApiKey;

        // 设置百度翻译配置
        BaiduTranslateAppIdTextBox.Text = translateConfig.BaiduConfig.AppId;
        BaiduTranslateSecretTextBox.Text = translateConfig.BaiduConfig.SecretKey;

        // 设置腾讯翻译配置
        TencentTranslateSecretIdTextBox.Text = translateConfig.TencentConfig.SecretId;
        TencentTranslateSecretKeyTextBox.Text = translateConfig.TencentConfig.SecretKey;

        // 显示对应的配置面板
        UpdateTranslateConfigVisibility();
    }

    /// <summary>
    /// 初始化其他API配置UI
    /// </summary>
    private void InitializeOtherApiUI()
    {
        // 设置天气API配置
        WeatherApiKeyTextBox.Text = _currentToolApiConfig.WeatherConfig.ApiKey;

        // 设置新闻API配置
        NewsApiKeyTextBox.Text = _currentToolApiConfig.NewsConfig.ApiKey;
    }

    /// <summary>
    /// 设置工具API事件
    /// </summary>
    private void SetupToolApiEvents()
    {
        // 搜索引擎选择事件
        GoogleSearchRadio.Checked += (s, e) => UpdateSearchConfigVisibility();
        BingSearchRadio.Checked += (s, e) => UpdateSearchConfigVisibility();
        SerperSearchRadio.Checked += (s, e) => UpdateSearchConfigVisibility();

        // 翻译服务选择事件
        GoogleTranslateRadio.Checked += (s, e) => UpdateTranslateConfigVisibility();
        BaiduTranslateRadio.Checked += (s, e) => UpdateTranslateConfigVisibility();
        TencentTranslateRadio.Checked += (s, e) => UpdateTranslateConfigVisibility();

        // API配置文本框变化事件，实时更新状态指示器
        GoogleApiKeyTextBox.TextChanged += (s, e) => OnApiConfigChanged();
        GoogleSearchEngineIdTextBox.TextChanged += (s, e) => OnApiConfigChanged();
        BingApiKeyTextBox.TextChanged += (s, e) => OnApiConfigChanged();
        SerperApiKeyTextBox.TextChanged += (s, e) => OnApiConfigChanged();
        GoogleTranslateApiKeyTextBox.TextChanged += (s, e) => OnApiConfigChanged();
        BaiduTranslateAppIdTextBox.TextChanged += (s, e) => OnApiConfigChanged();
        BaiduTranslateSecretTextBox.TextChanged += (s, e) => OnApiConfigChanged();
        TencentTranslateSecretIdTextBox.TextChanged += (s, e) => OnApiConfigChanged();
        TencentTranslateSecretKeyTextBox.TextChanged += (s, e) => OnApiConfigChanged();
        WeatherApiKeyTextBox.TextChanged += (s, e) => OnApiConfigChanged();
        NewsApiKeyTextBox.TextChanged += (s, e) => OnApiConfigChanged();
    }

    /// <summary>
    /// 更新搜索配置面板可见性
    /// </summary>
    private void UpdateSearchConfigVisibility()
    {
        GoogleSearchConfig.Visibility = GoogleSearchRadio.IsChecked == true ? Visibility.Visible : Visibility.Collapsed;
        BingSearchConfig.Visibility = BingSearchRadio.IsChecked == true ? Visibility.Visible : Visibility.Collapsed;
        SerperSearchConfig.Visibility = SerperSearchRadio.IsChecked == true ? Visibility.Visible : Visibility.Collapsed;
    }

    /// <summary>
    /// 更新翻译配置面板可见性
    /// </summary>
    private void UpdateTranslateConfigVisibility()
    {
        GoogleTranslateConfig.Visibility = GoogleTranslateRadio.IsChecked == true ? Visibility.Visible : Visibility.Collapsed;
        BaiduTranslateConfig.Visibility = BaiduTranslateRadio.IsChecked == true ? Visibility.Visible : Visibility.Collapsed;
        TencentTranslateConfig.Visibility = TencentTranslateRadio.IsChecked == true ? Visibility.Visible : Visibility.Collapsed;
    }

    /// <summary>
    /// 测试工具API
    /// </summary>
    private async void TestToolApi_Click(object sender, RoutedEventArgs e)
    {
        try
        {
            TestToolApiButton.IsEnabled = false;
            TestResultTextBox.Text = "正在测试...";

            var query = TestQueryTextBox.Text.Trim();
            if (string.IsNullOrEmpty(query))
            {
                TestResultTextBox.Text = "请输入测试查询";
                return;
            }

            // 获取当前配置
            var currentConfig = GetCurrentToolApiConfig();

            // 临时保存配置以便测试
            await _toolApiConfigService.SaveConfigAsync(currentConfig);

            // 测试搜索API
            var (success, result, errorMessage) = await _toolApiConfigService.TestSearchApiAsync(query);

            if (success)
            {
                TestResultTextBox.Text = result;
            }
            else
            {
                TestResultTextBox.Text = $"测试失败: {errorMessage}";
            }
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "测试工具API失败");
            TestResultTextBox.Text = $"测试时发生错误: {ex.Message}";
        }
        finally
        {
            TestToolApiButton.IsEnabled = true;
        }
    }

    /// <summary>
    /// 获取当前工具API配置
    /// </summary>
    private ToolApiConfig GetCurrentToolApiConfig()
    {
        var config = new ToolApiConfig();

        // 获取搜索配置
        config.SearchConfig.SearchEngine = GoogleSearchRadio.IsChecked == true ? "Google" :
                                          BingSearchRadio.IsChecked == true ? "Bing" : "Serper";

        config.SearchConfig.GoogleConfig.ApiKey = GoogleApiKeyTextBox.Text.Trim();
        config.SearchConfig.GoogleConfig.SearchEngineId = GoogleSearchEngineIdTextBox.Text.Trim();
        config.SearchConfig.BingConfig.ApiKey = BingApiKeyTextBox.Text.Trim();
        config.SearchConfig.SerperConfig.ApiKey = SerperApiKeyTextBox.Text.Trim();

        if (int.TryParse(SearchResultCountTextBox.Text, out int resultCount))
        {
            config.SearchConfig.ResultCount = resultCount;
        }
        config.SearchConfig.Language = SearchLanguageTextBox.Text.Trim();
        config.SearchConfig.SafeSearch = SafeSearchCheckBox.IsChecked == true;

        // 获取翻译配置
        config.TranslateConfig.TranslateService = GoogleTranslateRadio.IsChecked == true ? "Google" :
                                                BaiduTranslateRadio.IsChecked == true ? "Baidu" : "Tencent";

        config.TranslateConfig.GoogleConfig.ApiKey = GoogleTranslateApiKeyTextBox.Text.Trim();
        config.TranslateConfig.BaiduConfig.AppId = BaiduTranslateAppIdTextBox.Text.Trim();
        config.TranslateConfig.BaiduConfig.SecretKey = BaiduTranslateSecretTextBox.Text.Trim();
        config.TranslateConfig.TencentConfig.SecretId = TencentTranslateSecretIdTextBox.Text.Trim();
        config.TranslateConfig.TencentConfig.SecretKey = TencentTranslateSecretKeyTextBox.Text.Trim();

        // 获取其他API配置
        config.WeatherConfig.ApiKey = WeatherApiKeyTextBox.Text.Trim();
        config.NewsConfig.ApiKey = NewsApiKeyTextBox.Text.Trim();

        return config;
    }

    /// <summary>
    /// 更新工具状态指示器
    /// </summary>
    private void UpdateToolStatusIndicators(ToolApiConfig config)
    {
        try
        {
            var availability = config.GetToolAvailability();
            var greenBrush = new SolidColorBrush(Colors.Green);
            var redBrush = new SolidColorBrush(Colors.Red);

            // 更新状态指示器颜色
            SearchStatusIndicator.Fill = availability.IsSearchEnabled ? greenBrush : redBrush;
            TranslateStatusIndicator.Fill = availability.IsTranslateEnabled ? greenBrush : redBrush;
            WeatherStatusIndicator.Fill = availability.IsWeatherEnabled ? greenBrush : redBrush;
            NewsStatusIndicator.Fill = availability.IsNewsEnabled ? greenBrush : redBrush;

            // 更新状态文本
            var enabledCount = new[] { availability.IsSearchEnabled, availability.IsTranslateEnabled,
                                     availability.IsWeatherEnabled, availability.IsNewsEnabled }.Count(x => x);

            ToolStatusText.Text = enabledCount switch
            {
                4 => "所有工具已启用",
                0 => "所有工具已禁用（未填写APIkey）",
                _ => $"{enabledCount}/4 个工具已启用，其余工具因缺少APIkey而被禁用"
            };
        }
        catch (Exception ex)
        {
            _logger?.LogError(ex, "更新工具状态指示器失败");
        }
    }

    /// <summary>
    /// 当API配置文本框内容改变时更新状态指示器
    /// </summary>
    private void OnApiConfigChanged()
    {
        try
        {
            var config = GetCurrentToolApiConfig();
            UpdateToolStatusIndicators(config);
        }
        catch (Exception ex)
        {
            _logger?.LogError(ex, "更新API配置状态失败");
        }
    }

    #endregion

    #region RWKV事件处理









    private async void RWKVDetectModels_Click(object sender, RoutedEventArgs e)
    {
        try
        {
            UpdateStatus("正在检测RWKV模型...");
            RWKVDetectModelsButton.IsEnabled = false;

            // 构建RWKV配置
            var rwkvConfig = new RWKVConfig
            {
                BaseUrl = RWKVBaseUrlTextBox?.Text?.Trim() ?? "http://localhost:8000",
                ApiKey = RWKVApiKeyTextBox?.Text?.Trim() ?? ""
            };

            // 创建临时RWKV服务进行检测
            using var httpClient = new HttpClient();
            var rwkvService = new RWKVService(_logger as ILogger<RWKVService>, httpClient);
            rwkvService.UpdateConfig(rwkvConfig);

            var models = await rwkvService.GetAvailableModelsAsync();

            if (models.Any())
            {
                // 更新模型列表
                if (RWKVModelComboBox != null)
                {
                    RWKVModelComboBox.Items.Clear();
                    foreach (var model in models)
                    {
                        var item = new ComboBoxItem
                        {
                            Content = model.Id,
                            ToolTip = model.Description
                        };
                        RWKVModelComboBox.Items.Add(item);
                    }

                    if (RWKVModelComboBox.Items.Count > 0)
                    {
                        ((ComboBoxItem)RWKVModelComboBox.Items[0]).IsSelected = true;
                    }
                }

                UpdateStatus($"检测到{models.Count}个RWKV模型");
                MessageBox.Show($"成功检测到{models.Count}个RWKV模型", "检测完成", MessageBoxButton.OK, MessageBoxImage.Information);
            }
            else
            {
                UpdateStatus("未检测到RWKV模型");
                MessageBox.Show("未检测到可用的RWKV模型，请检查RWKV Runner是否正常运行", "检测结果", MessageBoxButton.OK, MessageBoxImage.Warning);
            }
        }
        catch (Exception ex)
        {
            _logger?.LogError(ex, "检测RWKV模型失败");
            UpdateStatus($"检测RWKV模型失败: {ex.Message}");
            MessageBox.Show($"检测RWKV模型失败：{ex.Message}", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
        }
        finally
        {
            RWKVDetectModelsButton.IsEnabled = true;
        }
    }

    #endregion

    #region 自定义模型管理

    /// <summary>
    /// 加载自定义模型到UI
    /// </summary>
    private void LoadCustomModelsToUI()
    {
        try
        {
            // 为各平台的ComboBox添加事件处理
            ZhipuModelComboBox.LostFocus += (s, e) => OnModelComboBoxLostFocus("ZhipuAI", ZhipuModelComboBox);
            DeepSeekModelComboBox.LostFocus += (s, e) => OnModelComboBoxLostFocus("DeepSeek", DeepSeekModelComboBox);
            OpenAIModelComboBox.LostFocus += (s, e) => OnModelComboBoxLostFocus("OpenAI", OpenAIModelComboBox);
            AlibabaModelComboBox.LostFocus += (s, e) => OnModelComboBoxLostFocus("Alibaba", AlibabaModelComboBox);
            RWKVModelComboBox.LostFocus += (s, e) => OnModelComboBoxLostFocus("RWKV", RWKVModelComboBox);

            // 加载已保存的自定义模型
            LoadCustomModelsForPlatform("ZhipuAI", ZhipuModelComboBox);
            LoadCustomModelsForPlatform("DeepSeek", DeepSeekModelComboBox);
            LoadCustomModelsForPlatform("OpenAI", OpenAIModelComboBox);
            LoadCustomModelsForPlatform("Alibaba", AlibabaModelComboBox);
            LoadCustomModelsForPlatform("RWKV", RWKVModelComboBox);

            _logger.LogInformation("自定义模型UI初始化完成");
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "加载自定义模型到UI失败");
        }
    }

    /// <summary>
    /// 为指定平台加载自定义模型
    /// </summary>
    private void LoadCustomModelsForPlatform(string platform, ComboBox comboBox)
    {
        try
        {
            var customModels = _customModelService.GetCustomModels(platform);
            foreach (var model in customModels)
            {
                // 检查是否已存在
                bool exists = false;
                foreach (ComboBoxItem item in comboBox.Items)
                {
                    if (item.Content?.ToString() == model)
                    {
                        exists = true;
                        break;
                    }
                }

                if (!exists)
                {
                    var newItem = new ComboBoxItem
                    {
                        Content = model,
                        ToolTip = $"自定义模型: {model}"
                    };
                    comboBox.Items.Add(newItem);
                }
            }
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, $"为平台 {platform} 加载自定义模型失败");
        }
    }

    /// <summary>
    /// 模型ComboBox失去焦点时的处理
    /// </summary>
    private async void OnModelComboBoxLostFocus(string platform, ComboBox comboBox)
    {
        try
        {
            var text = comboBox.Text?.Trim();
            if (string.IsNullOrEmpty(text))
                return;

            // 检查是否为新的自定义模型
            bool isNewModel = true;
            foreach (ComboBoxItem item in comboBox.Items)
            {
                if (item.Content?.ToString() == text)
                {
                    isNewModel = false;
                    break;
                }
            }

            if (isNewModel)
            {
                // 添加到自定义模型列表
                var success = await _customModelService.AddCustomModelAsync(platform, text);
                if (success)
                {
                    // 添加到ComboBox
                    var newItem = new ComboBoxItem
                    {
                        Content = text,
                        ToolTip = $"自定义模型: {text}"
                    };
                    comboBox.Items.Add(newItem);
                    comboBox.SelectedItem = newItem;

                    _logger.LogInformation($"添加新的自定义模型: {platform} - {text}");

                    // 显示提示消息
                    UpdateStatus($"已保存自定义模型: {text}");
                }
            }
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, $"处理自定义模型输入失败: {platform}");
        }
    }

    /// <summary>
    /// 获取选中的模型名称（支持自定义输入）
    /// </summary>
    private string GetSelectedModelName(ComboBox comboBox)
    {
        // 如果用户直接输入了文本，返回文本内容
        if (!string.IsNullOrWhiteSpace(comboBox.Text))
        {
            return comboBox.Text.Trim();
        }

        // 否则返回选中项的内容
        if (comboBox.SelectedItem is ComboBoxItem selectedItem)
        {
            return selectedItem.Content?.ToString() ?? "";
        }

        return "";
    }

    /// <summary>
    /// 清理未使用的自定义模型
    /// </summary>
    private async void CleanupCustomModels_Click(object sender, RoutedEventArgs e)
    {
        try
        {
            var result = MessageBox.Show(
                "是否清理重复的自定义模型？这将移除重复的模型名称。",
                "清理确认",
                MessageBoxButton.YesNo,
                MessageBoxImage.Question);

            if (result == MessageBoxResult.Yes)
            {
                await _customModelService.CleanupDuplicatesAsync();

                // 重新加载UI
                LoadCustomModelsToUI();

                MessageBox.Show("自定义模型清理完成！", "完成", MessageBoxButton.OK, MessageBoxImage.Information);
            }
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "清理自定义模型失败");
            MessageBox.Show($"清理失败：{ex.Message}", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
        }
    }

    #endregion
}
